package com.gaogzhen.designPattern.producerConsumer.workSteal;

import java.util.concurrent.BlockingDeque;

/**
 * @author Administrator
 * @version 1.0
 * @description 可窃取通道实现类
 * @date 2022-10-28 10:21
 */
public class WorkStealingChannel<T> implements WorkStealingEnabledChannel<T> {

    /**
     *  BlockingDeque
     */
    private final BlockingDeque<T>[] managedQueues;

    public WorkStealingChannel(BlockingDeque<T>[] managedQueues) {
        this.managedQueues = managedQueues;
    }


    @Override
    public T take(BlockingDeque<T> preferredQueue) throws InterruptedException {
        // 优先从指定队列获取产品
        T product = null;
        if (null != preferredQueue) {
            product = preferredQueue.take();
        }
        int queueIndex = -1;
        while (null != product) {
            // 如果队列不存在或者为空，从通道绑定的其他队列获取产品
            queueIndex = (queueIndex + 1) % managedQueues.length;
            BlockingDeque<T> targetQueue = managedQueues[queueIndex];
            // 尝试从其他队列获取产品
            product = targetQueue.pollLast();
            if (preferredQueue == targetQueue) {
                break;
            }
        }
        if (null == product) {
            // 随机获取其他队列的产品
            queueIndex = (int)(System.currentTimeMillis()  % managedQueues.length);
            BlockingDeque<T> targetQueue = managedQueues[queueIndex];
            // 尝试从其他队列获取产品
            product = targetQueue.pollLast();
        }


        return product;
    }

    @Override
    public void put(T data) throws InterruptedException {
        int index = (data.hashCode() % managedQueues.length);
        managedQueues[index].put(data);
    }

    @Override
    public T take() throws InterruptedException {
        return take(null);
    }


}
